// source --> https://juttersloep.nl/wp-content/plugins/recras/js/onlinebooking.min.js?ver=1.10.3 "use strict"; function _objectValues(obj) { var values = []; var keys = Object.keys(obj); for (var k = 0; k < keys.length; k++) values.push(obj[keys[k]]); return values; } function _objectEntries(obj) { var entries = []; var keys = Object.keys(obj); for (var k = 0; k < keys.length; k++) entries.push([keys[k], obj[keys[k]]]); return entries; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /******************************* * Recras integration library * * v 1.10.3 * *******************************/ var RecrasBooking = /*#__PURE__*/function () { function RecrasBooking() { var _this = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, RecrasBooking); this.datePicker = null; this.PAYMENT_DIRECT = 'mollie'; this.PAYMENT_AFTERWARDS = 'factuur'; this.RECRAS_INFINITY = 99999; // This is used instead of "true infinity" because JSON doesn't have infinity this.languageHelper = new RecrasLanguageHelper(); if (!(options instanceof RecrasOptions)) { throw new Error(this.languageHelper.translate('ERR_OPTIONS_INVALID')); } this.options = options; this.eventHelper = new RecrasEventHelper(); this.eventHelper.setAnalytics(this.options.getAnalytics()); this.eventHelper.setEvents(this.options.getAnalyticsEvents()); var optionsPromise = this.languageHelper.setOptions(options); this.element = this.options.getElement(); this.element.classList.add('recras-onlinebooking'); this.fetchJson = function (url) { return RecrasHttpHelper.fetchJson(url, _this.error); }; this.postJson = function (url, data) { return RecrasHttpHelper.postJson(_this.options.getApiBase() + url, data, _this.error.bind(_this)); }; if (this.options.getLocale()) { if (!RecrasLanguageHelper.isValid(this.options.getLocale())) { console.warn(this.languageHelper.translate('ERR_INVALID_LOCALE', { LOCALES: RecrasLanguageHelper.validLocales.join(', ') })); } else { this.languageHelper.setLocale(this.options.getLocale()); } } if (this.options.getPreFilledAmounts()) { if (!this.options.isSinglePackage()) { console.warn(this.languageHelper.translate('ERR_AMOUNTS_NO_PACKAGE')); } } if (this.options.getPreFilledDate()) { this.prefillDateIfPossible(); } if (this.options.getPreFilledTime()) { this.prefillTimeIfPossible(); } RecrasCSSHelper.loadCSS('global'); RecrasCSSHelper.loadCSS('booking'); RecrasCSSHelper.loadCSS('pikaday'); this.clearAll(); this.loadingIndicatorShow(this.element); this.promise = optionsPromise.then(function () { return RecrasCalendarHelper.loadScript(); }).then(function () { return _this.getTexts(); }).then(function (texts) { _this.texts = texts; return _this.getPackages(); }).then(function (packages) { _this.loadingIndicatorHide(); var pck = _this.options.getPackageId(); if (_this.options.isSinglePackage()) { if (Array.isArray(pck)) { pck = pck[0]; } return _this.changePackage(pck); } else if (Array.isArray(pck) && pck.length > 1) { packages = packages.filter(function (p) { return pck.includes(p.id); }); } return _this.showPackages(packages); }); } _createClass(RecrasBooking, [{ key: "prefillDateIfPossible", value: function prefillDateIfPossible() { var date = new Date(this.options.getPreFilledDate()); if (isNaN(date.getTime())) { console.warn(this.languageHelper.translate('ERR_INVALID_DATE')); return false; } if (date < new Date()) { console.warn(this.languageHelper.translate('ERR_DATE_PAST')); return false; } if (!this.options.isSinglePackage()) { console.warn(this.languageHelper.translate('ERR_DATE_NO_SINGLE_PACKAGE')); return false; } this.prefilledDate = date; return true; } }, { key: "prefillTimeIfPossible", value: function prefillTimeIfPossible() { var time = this.options.getPreFilledTime(); if (!time.match(/^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/)) { console.warn(this.languageHelper.translate('ERR_INVALID_TIME')); return false; } this.prefilledTime = time; return true; } }, { key: "hasAtLeastOneProduct", value: function hasAtLeastOneProduct(pack) { if (this.shouldShowBookingSize(pack) && this.bookingSize() > 0) { return true; } var hasAtLeastOneProduct = false; for (var _i2 = 0, _this$getLinesNoBooki2 = this.getLinesNoBookingSize(pack); _i2 < _this$getLinesNoBooki2.length; _i2++) { var line = _this$getLinesNoBooki2[_i2]; var lineEl = this.findElement("[data-package-id=\"".concat(line.id, "\"]")); if (lineEl && lineEl.value > 0) { hasAtLeastOneProduct = true; } } return hasAtLeastOneProduct; } }, { key: "amountsValid", value: function amountsValid(pack) { for (var _i4 = 0, _this$getLinesNoBooki4 = this.getLinesNoBookingSize(pack); _i4 < _this$getLinesNoBooki4.length; _i4++) { var line = _this$getLinesNoBooki4[_i4]; var lineEl = this.findElement("[data-package-id=\"".concat(line.id, "\"]")); if (!lineEl) { console.warn("Element for line ".concat(line.id, " not found")); return false; } var aantal = lineEl.value; if (aantal > 0 && aantal < line.aantal_personen) { return false; } if (aantal > 0 && line.min && aantal < line.min) { return false; } if (line.max && aantal > line.max) { return false; } } if (this.shouldShowBookingSize(pack) && this.bookingSize() > 0) { if (this.bookingSize() < this.bookingSizeMinimum(pack) || this.bookingSize() > this.bookingSizeMaximum(pack)) { return false; } } return this.hasAtLeastOneProduct(pack); } }, { key: "appendHtml", value: function appendHtml(msg) { this.element.insertAdjacentHTML('beforeend', msg); } }, { key: "applyVoucher", value: function applyVoucher(packageID, voucherCode) { var _this2 = this; if (!voucherCode) { this.setDiscountStatus(this.languageHelper.translate('VOUCHER_EMPTY')); return Promise.resolve(false); } if (this.appliedVouchers[voucherCode]) { this.setDiscountStatus(this.languageHelper.translate('VOUCHER_ALREADY_APPLIED')); return Promise.resolve(false); } if (!this.selectedDate) { this.setDiscountStatus(this.languageHelper.translate('DATE_INVALID')); return Promise.resolve(false); } return this.postJson('onlineboeking/controleervoucher', { arrangement_id: packageID, datum: RecrasDateHelper.datePartOnly(this.selectedDate), producten: this.productCounts(), vouchers: [voucherCode] }).then(function (json) { var result = json[voucherCode]; if (!result.valid) { return Promise.resolve(false); } _this2.appliedVouchers[voucherCode] = result.processed; _this2.showTotalPrice(); return true; }); } }, { key: "recheckDiscountCode", value: function recheckDiscountCode() { var _this3 = this; this.checkDiscountcode(this.selectedPackage.id, RecrasDateHelper.datePartOnly(this.selectedDate), this.discount.code).then(function (status) { if (status) { _this3.setDiscountStatus(_this3.languageHelper.translate('DISCOUNT_APPLIED'), false); } else { _this3.discount = null; _this3.showTotalPrice(); var statusEl = _this3.findElement('.discount-status'); if (statusEl) { statusEl.parentNode.removeChild(statusEl); } } }); } }, { key: "recheckVouchers", value: function recheckVouchers() { var voucherCodes = Object.keys(this.appliedVouchers); this.appliedVouchers = []; var promises = []; for (var _i6 = 0; _i6 < voucherCodes.length; _i6++) { var voucherCode = voucherCodes[_i6]; promises.push(this.applyVoucher(this.selectedPackage.id, voucherCode)); } return Promise.all(promises); } }, { key: "bookingSize", value: function bookingSize() { var bookingSizeEl = this.findElement('.bookingsize'); if (!bookingSizeEl) { return 0; } var bookingSizeValue = parseInt(bookingSizeEl.value, 10); if (isNaN(bookingSizeValue)) { return 0; } return bookingSizeValue; } }, { key: "bookingSizeLines", value: function bookingSizeLines(pack) { return pack.regels.filter(function (line) { return line.onlineboeking_aantalbepalingsmethode === 'boekingsgrootte'; }); } }, { key: "bookingSizeMaximum", value: function bookingSizeMaximum(pack) { var lines = this.bookingSizeLines(pack).filter(function (line) { return line.max; }); if (lines.length === 0) { return this.RECRAS_INFINITY; } var maxes = lines.map(function (line) { return line.max; }); return Math.min.apply(Math, _toConsumableArray(maxes)); } }, { key: "bookingSizeLineMinimum", value: function bookingSizeLineMinimum(line) { if (line.min) { return line.min; } if (line.onlineboeking_aantalbepalingsmethode === 'vast') { return 0; } return line.product.minimum_aantal; } }, { key: "bookingSizeMinimum", value: function bookingSizeMinimum(pack) { var _this4 = this; var minSize = 0; this.bookingSizeLines(pack).forEach(function (line) { minSize = Math.max(minSize, _this4.bookingSizeLineMinimum(line)); }); return minSize; } }, { key: "amountFromPersons", value: function amountFromPersons(product, persons) { return persons; //TODO: this doesn't work yet because public product API does not send: // aantalbepaling, aantal, per_x_personen_afronding, per_x_personen if (product.aantalbepaling === 'vast') { return product.aantal; } var fn = product.per_x_personen_afronding === 'beneden' ? Math.floor : Math.ceil; return product.aantal * fn(persons / product.per_x_personen); } }, { key: "bookingSizePrice", value: function bookingSizePrice(pack) { var _this5 = this; var nrOfPersons = Math.max(pack.aantal_personen, 1); var price = 0; var lines = this.bookingSizeLines(pack); lines.forEach(function (line) { price += Math.max(_this5.amountFromPersons(line.product, nrOfPersons), line.product.minimum_aantal) * parseFloat(line.product.verkoop); }); return price / nrOfPersons; } }, { key: "filterPackagesFromoptions", value: function filterPackagesFromoptions(packages) { var pck = this.options.getPackageId(); if (!Array.isArray(pck)) { return packages; } return packages.filter(function (p) { return pck.includes(p.id); }); } }, { key: "changePackage", value: function changePackage(packageID) { var _this6 = this; var selectedPackage = this.packages.filter(function (p) { return p.id === packageID; }); this.appliedVouchers = {}; this.discount = null; if (selectedPackage.length === 0) { // Reset form this.selectedPackage = null; this.clearAll(); var packages = this.filterPackagesFromoptions(this.packages); this.showPackages(packages); this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_RESET); return Promise.resolve(false); } else { this.clearAllExceptPackageSelection(); this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_PACKAGE_CHANGED, selectedPackage[0].arrangement, selectedPackage[0].id); } this.selectedPackage = selectedPackage[0]; return this.showProducts(this.selectedPackage).then(function () { _this6.nextSectionActive('.recras-package-select', '.recras-amountsform'); _this6.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_PRODUCTS_SHOWN); if (_this6.options.getAutoScroll() === true) { var scrollOptions = { behavior: 'smooth' }; if (!('scrollBehavior' in document.documentElement.style)) { scrollOptions = true; } _this6.findElement('.recras-amountsform').scrollIntoView(scrollOptions); } _this6.checkDependencies(); _this6.loadingIndicatorShow(_this6.findElement('.recras-amountsform')); return _this6.showDateTimeSelection(_this6.selectedPackage); }).then(function () { _this6.loadingIndicatorHide(); _this6.showContactForm(_this6.selectedPackage); }); } }, { key: "checkBookingSize", value: function checkBookingSize(pack) { if (!this.shouldShowBookingSize(pack)) { return; } var bookingSize = this.bookingSize(); var bsMaximum = this.bookingSizeMaximum(pack); var bsMinimum = this.bookingSizeMinimum(pack); if (bookingSize < bsMinimum) { this.setMinMaxAmountWarning('bookingsize', bsMinimum, 'minimum'); } else if (bookingSize > bsMaximum) { this.setMinMaxAmountWarning('bookingsize', bsMaximum, 'maximum'); } this.maybeDisableBookButton(); } }, { key: "checkDependencies", value: function checkDependencies() { var _this7 = this; _toConsumableArray(this.findElements('.recras-product-dependency')).forEach(function (el) { el.parentNode.removeChild(el); }); _toConsumableArray(this.findElements('[data-package-id]')).forEach(function (el) { el.classList.remove('recras-input-invalid'); }); this.requiresProduct = false; this.productCounts().forEach(function (line) { if (line.aantal > 0) { var packageLineID = line.arrangementsregel_id; var product = _this7.findProduct(packageLineID).product; var thisProductRequiresProduct = false; if (!product.vereist_product) { console.warn('You are logged in to this particular Recras. Because of API differences between logged-in and logged-out state, required products do not work as expected.'); } else { product.vereist_product.forEach(function (vp) { if (!_this7.dependencySatisfied(line.aantal, vp)) { thisProductRequiresProduct = true; _this7.requiresProduct = true; var requiredAmount = _this7.requiredAmount(line.aantal, vp); var requiredProductName = _this7.getProductByID(vp.vereist_product_id).weergavenaam; var message = _this7.languageHelper.translate('PRODUCT_REQUIRED', { NUM: line.aantal, PRODUCT: product.weergavenaam, REQUIRED_AMOUNT: requiredAmount, REQUIRED_PRODUCT: requiredProductName }); _this7.findElement('.recras-amountsform').insertAdjacentHTML('beforeend', "".concat(message, "")); } }); } if (thisProductRequiresProduct) { var productInput = _this7.findElement("[data-package-id=\"".concat(packageLineID, "\"]")); productInput.classList.add('recras-input-invalid'); } } }); this.maybeDisableBookButton(); } }, { key: "checkDiscountAndVoucher", value: function checkDiscountAndVoucher() { var _this8 = this; var discountPromise = this.checkDiscountcode(this.selectedPackage.id, RecrasDateHelper.datePartOnly(this.selectedDate), this.findElement('#discountcode').value.trim()); var voucherPromise = this.applyVoucher(this.selectedPackage.id, this.findElement('#discountcode').value.trim()); Promise.all([discountPromise, voucherPromise]).then(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), discountStatus = _ref2[0], voucherStatus = _ref2[1]; if (discountStatus || voucherStatus) { var status; if (discountStatus) { status = 'DISCOUNT_APPLIED'; } else { status = 'VOUCHER_APPLIED'; } _this8.setDiscountStatus(_this8.languageHelper.translate(status), false); _this8.findElement('#discountcode').value = ''; _this8.nextSectionActive('.recras-discounts', '.recras-contactform'); } else { _this8.setDiscountStatus(_this8.languageHelper.translate('DISCOUNT_INVALID')); } }); } }, { key: "checkDiscountcode", value: function checkDiscountcode(packageID, date, code) { var _this9 = this; return this.fetchJson(this.options.getApiBase() + 'onlineboeking/controleerkortingscode' + '?datum=' + date + '&arrangement=' + packageID + '&kortingscode=' + encodeURIComponent(code)).then(function (discount) { if (discount === false) { return false; } discount.code = code; _this9.discount = discount; _this9.showTotalPrice(); return true; }); } }, { key: "checkMaximumForPackage", value: function checkMaximumForPackage() { var _this10 = this; var maxPerLine = this.selectedPackage.maximum_aantal_personen_online; if (maxPerLine === null) { return Promise.resolve(null); } var showWarning = false; var selectedProducts = this.productCounts(); return this.languageHelper.filterTags(this.texts.maximum_aantal_online_boeking_overschreden, this.selectedPackage ? this.selectedPackage.id : null).then(function (msg) { selectedProducts.forEach(function (p) { if (p.aantal > maxPerLine && !showWarning) { var input = _this10.findElement("[data-package-id=\"".concat(p.arrangementsregel_id, "\"]")); if (!input) { input = _this10.findElement('#bookingsize'); } if (input) { var warningEl = document.createElement('div'); warningEl.classList.add('maximum-amount'); warningEl.classList.add('recras-full-width'); warningEl.innerHTML = msg; input.parentNode.parentNode.insertBefore(warningEl, input.parentNode.nextSibling); input.classList.add('recras-input-invalid'); } else { _this10.findElement('.recras-amountsform').insertAdjacentHTML('beforeend', "".concat(msg, "")); } showWarning = true; } }); }); } }, { key: "contactFormValid", value: function contactFormValid() { var contactFormIsValid = this.findElement('.recras-contactform').checkValidity(); var contactFormRequiredCheckboxes = this.contactForm.checkRequiredCheckboxes(); return contactFormIsValid && contactFormRequiredCheckboxes; } }, { key: "setMinMaxAmountWarning", value: function setMinMaxAmountWarning(lineID, minAmount) { var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'minimum'; var warnEl = document.createElement('span'); warnEl.classList.add(type + '-amount'); var lineEl = this.findElement("#".concat(lineID)); if (!lineEl) { console.warn("Element for line ".concat(lineID, " not found")); return false; } lineEl.classList.add('recras-input-invalid'); var text; if (type === 'minimum') { text = this.languageHelper.translate('PRODUCT_MINIMUM', { MINIMUM: minAmount }); } else { text = this.languageHelper.translate('PRODUCT_MAXIMUM', { MAXIMUM: minAmount }); } warnEl.innerHTML = text; var label = this.findElement("label[for=\"".concat(lineID, "\"]")); label.parentNode.appendChild(warnEl); } }, { key: "checkMinMaxAmounts", value: function checkMinMaxAmounts() { for (var _i8 = 0, _this$productCounts2 = this.productCounts(); _i8 < _this$productCounts2.length; _i8++) { var product = _this$productCounts2[_i8]; if (product.aantal < 1) { continue; } var packageLineID = product.arrangementsregel_id; var packageLine = this.findProduct(packageLineID); var input = this.findElement("[data-package-id=\"".concat(packageLineID, "\"]")); if (!input) { // This is a "booking size" line - this is handled in checkBookingSize continue; } if (product.aantal < packageLine.product.minimum_aantal) { this.setMinMaxAmountWarning(input.id, packageLine.product.minimum_aantal, 'minimum'); } else if (product.aantal < packageLine.aantal_personen) { this.setMinMaxAmountWarning(input.id, packageLine.aantal_personen, 'minimum'); } else if (packageLine.min !== undefined && product.aantal < packageLine.min) { this.setMinMaxAmountWarning(input.id, packageLine.min, 'minimum'); } else if (packageLine.max !== null && product.aantal > packageLine.max) { this.setMinMaxAmountWarning(input.id, packageLine.max, 'maximum'); } } } }, { key: "clearAll", value: function clearAll() { this.clearElements(this.element.children); } }, { key: "clearAllExceptPackageSelection", value: function clearAllExceptPackageSelection() { var packageSelect = this.findElement('.recras-package-select'); if (packageSelect) { packageSelect.classList.remove('recras-completed'); packageSelect.classList.add('recras-active'); } var elements = document.querySelectorAll('#' + this.element.id + ' > *:not(.recras-package-select)'); this.clearElements(elements); } }, { key: "clearElements", value: function clearElements(elements) { if (this.datePicker) { this.datePicker.destroy(); } this.availableDays = []; _toConsumableArray(elements).forEach(function (el) { el.parentNode.removeChild(el); }); this.maybeAddLatestErrorElement(); } }, { key: "dependencySatisfied", value: function dependencySatisfied(hasNow, requiredProduct) { for (var _i10 = 0, _this$productCounts4 = this.productCounts(); _i10 < _this$productCounts4.length; _i10++) { var line = _this$productCounts4[_i10]; if (line.aantal === 0) { continue; } var product = this.findProduct(line.arrangementsregel_id).product; if (product.id !== parseInt(requiredProduct.vereist_product_id, 10)) { continue; } var requiredAmount = this.requiredAmount(hasNow, requiredProduct); return line.aantal >= requiredAmount; } return false; } }, { key: "error", value: function error(msg) { this.loadingIndicatorHide(); var bookingErrorsEl = this.findElement('#bookingErrors'); if (bookingErrorsEl) { bookingErrorsEl.parentNode.appendChild(this.findElement('.latestError')); } this.maybeAddLatestErrorElement(); this.findElement('.latestError').innerHTML = "".concat(this.languageHelper.translate('ERR_GENERAL'), "

").concat(msg, "

"); } }, { key: "findElement", value: function findElement(querystring) { return this.element.querySelector(querystring); } }, { key: "findElements", value: function findElements(querystring) { return this.element.querySelectorAll(querystring); } }, { key: "findProduct", value: function findProduct(packageLineID) { return this.selectedPackage.regels.filter(function (line) { return line.id === packageLineID; })[0]; } }, { key: "formatPrice", value: function formatPrice(price) { return this.languageHelper.formatPrice(price); } }, { key: "getAvailableDays", value: function getAvailableDays(packageID, begin, end) { var _this11 = this; var postData = { arrangement_id: packageID, begin: RecrasDateHelper.datePartOnly(begin), eind: RecrasDateHelper.datePartOnly(end), producten: this.productCountsNoBookingSize() }; if (this.shouldShowBookingSize(this.selectedPackage)) { postData.boekingsgrootte = this.bookingSize(); } return this.postJson('onlineboeking/beschikbaredagen', postData).then(function (json) { _this11.availableDays = _this11.availableDays.concat(json); return _this11.availableDays; }); } }, { key: "getAvailableTimes", value: function getAvailableTimes(packageID, date) { var _this12 = this; return this.postJson('onlineboeking/beschikbaretijden', { arrangement_id: packageID, datum: RecrasDateHelper.datePartOnly(date), producten: this.productCounts() }).then(function (json) { _this12.availableTimes = json; return _this12.availableTimes; }); } }, { key: "getContactForm", value: function getContactForm(pack) { var _this13 = this; this.options.setOption('form_id', pack.onlineboeking_contactformulier_id); var contactForm = new RecrasContactForm(this.options); return contactForm.getContactFormFields().then(function () { _this13.contactForm = contactForm; return contactForm; }); } }, { key: "getDiscountPrice", value: function getDiscountPrice(discount) { if (!discount) { return 0; } return discount.percentage / 100 * this.getSubTotal() * -1; } }, { key: "getLinesBookingSize", value: function getLinesBookingSize(pack) { return pack.regels.filter(function (line) { return line.onlineboeking_aantalbepalingsmethode === 'boekingsgrootte'; }); } }, { key: "getLinesNoBookingSize", value: function getLinesNoBookingSize(pack) { return pack.regels.filter(function (line) { return line.onlineboeking_aantalbepalingsmethode !== 'boekingsgrootte'; }); } }, { key: "getPackages", value: function getPackages() { var _this14 = this; return this.fetchJson(this.options.getApiBase() + 'arrangementen').then(function (json) { _this14.packages = json; return _this14.packages; }); } }, { key: "getProductByID", value: function getProductByID(id) { var products = this.selectedPackage.regels.map(function (r) { return r.product; }); return products.filter(function (p) { return p.id === id; })[0]; } }, { key: "getSubTotal", value: function getSubTotal() { var _this15 = this; var total = 0; this.productCounts().forEach(function (line) { var product = _this15.findProduct(line.arrangementsregel_id).product; var aantal = line.aantal; if (isNaN(aantal)) { aantal = 0; } total += aantal * parseFloat(product.verkoop); }); return total; } }, { key: "getSetting", value: function getSetting(settingName) { return this.fetchJson(this.options.getApiBase() + 'instellingen/' + settingName); } }, { key: "getTexts", value: function getTexts() { var settings = ['maximum_aantal_online_boeking_overschreden', 'online_boeking_betaalkeuze', 'online_boeking_betaalkeuze_achteraf_titel', 'online_boeking_betaalkeuze_ideal_titel', 'online_boeking_step0_text_pre', 'online_boeking_step0_text_post', 'online_boeking_step1_text_pre', 'online_boeking_step1_text_post', 'online_boeking_step3_text_post']; var promises = []; for (var _i12 = 0; _i12 < settings.length; _i12++) { var setting = settings[_i12]; promises.push(this.getSetting(setting)); } return Promise.all(promises).then(function (settings) { var texts = {}; settings.forEach(function (setting) { texts[setting.slug] = setting.waarde; }); return texts; }); } }, { key: "getTotalPrice", value: function getTotalPrice() { var total = this.getSubTotal(); total += this.getDiscountPrice(this.discount); total += this.getVouchersPrice(); return total; } }, { key: "getVouchersPrice", value: function getVouchersPrice() { var voucherPrice = 0; _objectValues(this.appliedVouchers).forEach(function (voucher) { _objectValues(voucher).forEach(function (line) { voucherPrice -= line.aantal * line.prijs_per_stuk; }); }); return voucherPrice; } }, { key: "loadingIndicatorHide", value: function loadingIndicatorHide() { _toConsumableArray(document.querySelectorAll('.recrasLoadingIndicator')).forEach(function (el) { el.parentNode.removeChild(el); }); } }, { key: "loadingIndicatorShow", value: function loadingIndicatorShow(afterEl) { if (!afterEl) { return; } afterEl.insertAdjacentHTML('beforeend', "".concat(this.languageHelper.translate('LOADING'), "")); } }, { key: "maybeAddLatestErrorElement", value: function maybeAddLatestErrorElement() { var errorEl = this.findElement('.latestError'); if (!errorEl) { this.appendHtml("
"); } } }, { key: "maybeDisableBookButton", value: function maybeDisableBookButton() { var _this16 = this; var button = this.findElement('.bookPackage'); if (!button) { return false; } var bookingDisabledReasons = []; if (this.requiresProduct) { bookingDisabledReasons.push('BOOKING_DISABLED_REQUIRED_PRODUCT'); } if (!this.amountsValid(this.selectedPackage)) { bookingDisabledReasons.push('BOOKING_DISABLED_AMOUNTS_INVALID'); } if (!this.selectedDate) { bookingDisabledReasons.push('BOOKING_DISABLED_INVALID_DATE'); } if (!this.selectedTime) { bookingDisabledReasons.push('BOOKING_DISABLED_INVALID_TIME'); } if (!this.contactFormValid()) { bookingDisabledReasons.push('BOOKING_DISABLED_CONTACT_FORM_INVALID'); } var agreeEl = this.findElement('#recrasAgreeToAttachments'); if (agreeEl && !agreeEl.checked) { bookingDisabledReasons.push('BOOKING_DISABLED_AGREEMENT'); } if (bookingDisabledReasons.length > 0) { var reasonsList = bookingDisabledReasons.map(function (reason) { return _this16.languageHelper.translate(reason); }).join('
  • '); this.findElement('#bookingErrors').innerHTML = ""); button.setAttribute('disabled', 'disabled'); } else { this.findElement('#bookingErrors').innerHTML = ''; button.removeAttribute('disabled'); } } }, { key: "nextSectionActive", value: function nextSectionActive(completedQuery, activeQuery) { if (completedQuery && this.findElement(completedQuery)) { this.findElement(completedQuery).classList.add('recras-completed'); this.findElement(completedQuery).classList.remove('recras-active'); } //TODO: remove active from all sections? Test with invalid amount if (activeQuery && this.findElement(activeQuery)) { this.findElement(activeQuery).classList.add('recras-active'); } } }, { key: "normaliseDate", value: function normaliseDate(date, packageStart, bookingStart) { var diffSeconds = (date - packageStart) / 1000; var tempDate = new Date(bookingStart.getTime()); return new Date(tempDate.setSeconds(tempDate.getSeconds() + diffSeconds)); } }, { key: "paymentMethods", value: function paymentMethods(pack) { var methods = []; if (pack.mag_online_geboekt_worden_direct_betalen) { methods.push(this.PAYMENT_DIRECT); } if (pack.mag_online_geboekt_worden_achteraf_betalen) { methods.push(this.PAYMENT_AFTERWARDS); } return methods; } }, { key: "preFillAmounts", value: function preFillAmounts(amounts) { var _this17 = this; _objectEntries(amounts).forEach(function (idAmount) { var el; if (idAmount[0] === 'bookingsize') { el = _this17.findElement('#bookingsize'); } else { el = _this17.findElement("[data-package-id=\"".concat(idAmount[0], "\"]")); } if (el) { el.value = idAmount[1]; _this17.updateProductPrice(el); } }); this.updateProductAmounts(); } }, { key: "previewTimes", value: function previewTimes() { var _this18 = this; _toConsumableArray(this.findElements('.time-preview')).forEach(function (el) { el.parentNode.removeChild(el); }); if (this.selectedTime) { var linesWithTime = this.selectedPackage.regels.filter(function (line) { return !!line.begin; }); var linesBegin = linesWithTime.map(function (line) { return new Date(line.begin); }); var packageStart = new Date(Math.min.apply(Math, _toConsumableArray(linesBegin))); // Math.min transforms dates to timestamps var linesNoBookingSize = this.getLinesNoBookingSize(this.selectedPackage); linesNoBookingSize.forEach(function (line, idx) { if (line.begin !== null || line.eind !== null) { var normalisedStart = _this18.normaliseDate(new Date(line.begin), packageStart, _this18.selectedDate); var normalisedEnd = _this18.normaliseDate(new Date(line.eind), packageStart, _this18.selectedDate); _this18.findElement("label[for=\"packageline".concat(idx, "\"]")).insertAdjacentHTML('afterbegin', "".concat(RecrasDateHelper.timePartOnly(normalisedStart), " \u2013 ").concat(RecrasDateHelper.timePartOnly(normalisedEnd), "")); } }); } } }, { key: "productCountsBookingSize", value: function productCountsBookingSize() { var _this19 = this; return this.getLinesBookingSize(this.selectedPackage).map(function (line) { return { aantal: _this19.bookingSize(), arrangementsregel_id: line.id }; }); } }, { key: "productCountsNoBookingSize", value: function productCountsNoBookingSize() { return _toConsumableArray(this.findElements('[id^="packageline"]')).map(function (line) { return { aantal: isNaN(parseInt(line.value)) ? 0 : parseInt(line.value), arrangementsregel_id: parseInt(line.dataset.packageId, 10) }; }); } }, { key: "productCounts", value: function productCounts() { var counts = []; counts = counts.concat(this.productCountsNoBookingSize()); counts = counts.concat(this.productCountsBookingSize()); return counts; } }, { key: "removeWarnings", value: function removeWarnings() { _toConsumableArray(this.findElements('.booking-error:not(#bookingErrors)')).forEach(function (el) { el.parentNode.removeChild(el); }); _toConsumableArray(this.findElements('.minimum-amount')).forEach(function (el) { el.parentNode.removeChild(el); }); _toConsumableArray(this.findElements('.maximum-amount')).forEach(function (el) { el.parentNode.removeChild(el); }); _toConsumableArray(this.findElements('.recras-input-invalid')).forEach(function (el) { el.classList.remove('recras-input-invalid'); }); _toConsumableArray(this.findElements('.recras-success')).forEach(function (el) { el.parentNode.removeChild(el); }); } /** * requiredAmount calculates the amount N needed of Y in the sentence 'product X requires N times product Y' * * @param {number} hasNow The amount of product X selected * @param {object} requiredProduct * @param {number} requiredProduct.aantal The base amount of Y required * @param {number} requiredProduct.per_x_aantal The quantum of X that will require product Y * @param {"boven"|"beneden"} requiredProduct.afronding Indication of how hasNow / per_x_aantal should be rounded ("boven" will round up, "beneden" will round down) * @return {number} The amount of product Y needed */ }, { key: "requiredAmount", value: function requiredAmount(hasNow, requiredProduct) { var requiredFraction = hasNow / requiredProduct.per_x_aantal; if (requiredProduct.afronding === 'boven') { requiredFraction = Math.ceil(requiredFraction); } else { requiredFraction = Math.floor(requiredFraction); } return requiredProduct.aantal * requiredFraction; } }, { key: "resetForm", value: function resetForm() { this.changePackage(null); } }, { key: "selectSingleTime", value: function selectSingleTime() { if (this.findElements('#recras-onlinebooking-time option[value]').length !== 1) { return; } this.findElement('#recras-onlinebooking-time option[value]').selected = true; var event; try { event = new Event('change'); } catch (e) { // IE event = document.createEvent('Event'); event.initEvent('change', true, true); } this.findElement('#recras-onlinebooking-time').dispatchEvent(event); } }, { key: "setDiscountStatus", value: function setDiscountStatus(statusText) { var isError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var statusEl = this.findElement('.discount-status'); if (!statusEl) { this.element.querySelector('.recras-discounts').insertAdjacentHTML('beforeend', ""); statusEl = this.findElement('.discount-status'); } if (isError) { statusEl.classList.add('booking-error'); } else { statusEl.classList.remove('booking-error'); } statusEl.innerHTML = statusText; } }, { key: "setHtml", value: function setHtml(msg) { this.element.innerHTML = msg; } }, { key: "showStandardAttachments", value: function showStandardAttachments() { if (!this.selectedPackage || !this.findElement('.standard-attachments')) { return true; } var attachments = this.standardAttachments(this.selectedPackage); var attachmentHtml = ""; if (Object.keys(attachments).length) { attachmentHtml += "

    "); attachmentHtml += ""; } this.findElement('.standard-attachments').innerHTML = attachmentHtml; var agreeEl = this.findElement('#recrasAgreeToAttachments'); if (agreeEl) { agreeEl.addEventListener('change', this.maybeDisableBookButton.bind(this)); } } }, { key: "showTotalPrice", value: function showTotalPrice() { _toConsumableArray(this.findElements('.discountLine, .voucherLine, .priceWithDiscount')).forEach(function (el) { el.parentNode.removeChild(el); }); var html = ""; if (this.discount) { html += "
    ".concat(this.discount.naam, "
    ").concat(this.formatPrice(this.getDiscountPrice(this.discount)), "
    "); } if (Object.keys(this.appliedVouchers).length) { html += "
    ".concat(this.languageHelper.translate('VOUCHERS_DISCOUNT'), "
    ").concat(this.formatPrice(this.getVouchersPrice()), "
    "); } if (this.discount || Object.keys(this.appliedVouchers).length) { html += "
    ".concat(this.languageHelper.translate('PRICE_TOTAL_WITH_DISCOUNT'), "
    ").concat(this.formatPrice(this.getTotalPrice()), "
    "); } var elementToInsertBefore = this.findElement('.recras-amountsform p:last-of-type'); if (elementToInsertBefore) { elementToInsertBefore.insertAdjacentHTML('beforebegin', html); } var subtotalEl = this.findElement('.priceSubtotal'); if (subtotalEl) { subtotalEl.innerHTML = this.formatPrice(this.getSubTotal()); } } }, { key: "sortPackages", value: function sortPackages(packages) { // Packages from the API are sorted by internal name, not by display name // However, display name is not required so fallback to internal name return packages.sort(function (a, b) { var aName = a.weergavenaam || a.arrangement; var bName = b.weergavenaam || b.arrangement; if (aName < bName) { return -1; } if (aName > bName) { return 1; } return 0; }); } }, { key: "shouldShowBookingSize", value: function shouldShowBookingSize(pack) { return this.bookingSizeLines(pack).length > 0; } }, { key: "showBookButton", value: function showBookButton() { var _this20 = this; var promises = []; var paymentMethods = this.paymentMethods(this.selectedPackage); var paymentText = ''; var textPostBooking = ''; if (paymentMethods.indexOf(this.PAYMENT_DIRECT) > -1 && paymentMethods.indexOf(this.PAYMENT_AFTERWARDS) > -1) { // Let user decide how to pay promises.push(this.languageHelper.filterTags(this.texts.online_boeking_betaalkeuze, this.selectedPackage ? this.selectedPackage.id : null)); promises.push(this.languageHelper.filterTags(this.texts.online_boeking_betaalkeuze_ideal_titel, this.selectedPackage ? this.selectedPackage.id : null)); promises.push(this.languageHelper.filterTags(this.texts.online_boeking_betaalkeuze_achteraf_titel, this.selectedPackage ? this.selectedPackage.id : null)); Promise.all(promises).then(function (msgs) { paymentText = "

    ".concat(msgs[0], "

    "); paymentText += ""); }); } else { // One fixed choice promises.push(Promise.resolve('')); } promises.push(this.languageHelper.filterTags(this.texts.online_boeking_step3_text_post, this.selectedPackage ? this.selectedPackage.id : null).then(function (msg) { textPostBooking = msg; })); Promise.all(promises).then(function () { var html = "
    \n

    ".concat(textPostBooking, "

    \n
    \n ").concat(paymentText, "\n \n
    \n
    "); _this20.appendHtml(html); _this20.findElement('.bookPackage').addEventListener('click', _this20.submitBooking.bind(_this20)); _this20.maybeDisableBookButton(); _this20.updateProductAmounts(); }); } }, { key: "showDiscountFields", value: function showDiscountFields() { var _this21 = this; var existingEl = this.findElement('.recras-discounts'); if (existingEl) { existingEl.parentNode.removeChild(existingEl); } var html = "\n
    \n
    \n \n \n
    \n \n
    \n "); this.findElement('.recras-datetime').insertAdjacentHTML('afterend', html); this.findElement('.recras-discounts').addEventListener('submit', function (e) { e.preventDefault(); _this21.checkDiscountAndVoucher(); return false; }); } }, { key: "showContactForm", value: function showContactForm(pack) { var _this22 = this; this.loadingIndicatorShow(this.findElement('.recras-datetime')); this.getContactForm(pack).then(function (form) { return form.generateForm(); }).then(function (html) { _this22.appendHtml(html); _this22.loadingIndicatorHide(); _this22.showBookButton(); _this22.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_CONTACT_FORM_SHOWN); _toConsumableArray(_this22.findElements('[name^="contactformulier"]')).forEach(function (el) { el.addEventListener('input', _this22.maybeDisableBookButton.bind(_this22)); el.addEventListener('input', function () { if (_this22.contactFormValid()) { _this22.nextSectionActive('.recras-contactform', '.recras-finalise'); } }); }); }); } }, { key: "maybeFillTime", value: function maybeFillTime(times) { times = times.map(function (time) { return RecrasDateHelper.timePartOnly(new Date(time)); }); this.showTimes(times); this.loadingIndicatorHide(); if (!this.prefilledTime) { this.selectSingleTime(); return; } if (times.includes(this.prefilledTime)) { this.selectTime(this.prefilledTime); this.selectedDate = RecrasDateHelper.setTimeForDate(this.selectedDate, this.selectedTime); if (this.options.getPreviewTimes() === true) { this.previewTimes(); } return; } this.toggleTimeField('show'); } }, { key: "calendarOnDateSelect", value: function calendarOnDateSelect(date, packageId) { var _this23 = this; this.removeWarnings(); this.loadingIndicatorShow(this.findElement('label[for="recras-onlinebooking-time"]')); this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_DATE_SELECTED, RecrasDateHelper.datePartOnly(date)); this.selectedDate = date; if (this.hasAtLeastOneProduct(this.selectedPackage)) { this.getAvailableTimes(packageId, date).then(function (times) { return _this23.maybeFillTime(times); }); } if (this.discount && this.discount.code) { this.recheckDiscountCode(); } this.findElement('#discountcode').removeAttribute('disabled'); this.maybeDisableBookButton(); } }, { key: "calendarOnDraw", value: function calendarOnDraw(pika, packageId) { var lastMonthYear = pika.calendars[pika.calendars.length - 1]; var lastDay = new Date(lastMonthYear.year, lastMonthYear.month, 31); var lastAvailableDay = this.availableDays.reduce(function (acc, curVal) { return curVal > acc ? curVal : acc; }, ''); if (!lastAvailableDay) { lastAvailableDay = new Date(); } else { lastAvailableDay = new Date(lastAvailableDay); } if (lastAvailableDay > lastDay) { return; } var newEndDate = RecrasDateHelper.clone(lastAvailableDay); newEndDate.setFullYear(lastMonthYear.year); newEndDate.setMonth(lastMonthYear.month + 2); this.getAvailableDays(packageId, lastAvailableDay, newEndDate); } }, { key: "addDateTimeSelectionHtml", value: function addDateTimeSelectionHtml() { var today = RecrasDateHelper.datePartOnly(new Date()); var html = "
    \n \n \n \n \n
    "); this.appendHtml(html); } }, { key: "selectTime", value: function selectTime(time) { this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_TIME_SELECTED); this.selectedTime = time; this.maybeDisableBookButton(); } }, { key: "showDateTimeSelection", value: function showDateTimeSelection(pack) { var _this24 = this; this.addDateTimeSelectionHtml(); this.showDiscountFields(); if (this.prefilledDate) { this.toggleDateField('hide'); this.calendarOnDateSelect(this.prefilledDate, pack.id); } if (this.prefilledTime) { this.toggleTimeField('hide'); } if (this.prefilledDate && this.prefilledTime) { this.findElement('.recras-datetime').classList.add('recrasHidden'); } if (this.options.getPreFilledAmounts()) { this.preFillAmounts(this.options.getPreFilledAmounts()); } var pikadayOptions = _extends(RecrasCalendarHelper.defaultOptions(), { disableDayFn: function disableDayFn(day) { var dateFmt = RecrasDateHelper.datePartOnly(day); return _this24.availableDays.indexOf(dateFmt) === -1; }, field: this.findElement('.recras-onlinebooking-date'), i18n: RecrasCalendarHelper.i18n(this.languageHelper), onDraw: function onDraw(pika) { return _this24.calendarOnDraw(pika, pack.id); }, onSelect: function onSelect(date) { return _this24.calendarOnDateSelect(date, pack.id); } }); this.datePicker = new Pikaday(pikadayOptions); this.findElement('.recras-onlinebooking-time').addEventListener('change', function () { _this24.selectTime(_this24.findElement('.recras-onlinebooking-time').value); _this24.nextSectionActive('.recras-datetime', '.recras-discounts'); _this24.nextSectionActive(null, '.recras-contactform'); _this24.selectedDate = RecrasDateHelper.setTimeForDate(_this24.selectedDate, _this24.selectedTime); if (_this24.options.getPreviewTimes() === true) { _this24.previewTimes(); } _this24.maybeDisableBookButton(); }); } }, { key: "showPackages", value: function showPackages(packages) { var _this25 = this; packages = packages.filter(function (p) { return p.mag_online; }); var packagesSorted = this.sortPackages(packages); var packageOptions = packagesSorted.map(function (pack) { return "